package encrypt

import (
	"sync"
	"encoding/base64"
	"strings"
	"github.com/pquerna/ffjson/ffjson"
)


var privateKey = string(`
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQChSqXhDsX++VxIhy4LnjYcZ1WLHoyp6Pc30V6DtT36+iqr4JSS
dhfhQACmLFaAnYZJ+7yDsNpsnLO3eBFYQV3S+M/F6b7eTRxAg/6TTmfPiRI9T3kt
+Bkr7bMH+upHYUSJluK7i0DBFp479mKoI5gpFlqkinj04vaXSEB4GuoglwIDAQAB
AoGAXeM7Hf/gh2SWMG3oAsFM1EnehMX6sak3xxksAFUPSDo5fqWTNpJhojAEcLac
f++yTPyppqra6qBpCOJujkY2m3y4kSuViDXNONe2msITEaU5SfGESNxAV5MneBFL
Pc7S5ZfF/4EFRfcXsx68f4kodoJgZI7Nsd2H1fuWvf/wYVECQQDO6Iqwv/xvN5h9
d2P6zhp0crd5O2EksFRYKSS4fBzlHmSyOKbt6wrjIdO6adNF4hh85MdW9Wobz+Fx
agQFyBY5AkEAx49guFYuUwXIK1vyHYIMQwUqg7vhuAQLX2eMaB1WQd66VQxhl0iN
bqQ7lFh0aUUkbGZc+aCKX7C1ew9Efl1tTwJAQK+w1GthN0ARW4Bc8IdI/Aj1VWB8
EWVTKTDLuyWKPxNOde2COrWV9MaZlBkLpTh3YWyA6a3WG5XVLIjxcwFH+QJAE6Y9
eskZlJksJYDPLTKh7HN0xTXZutnDGOjEPXguBxxcMoWeklvVeUB4kVnIVJk3Rekq
XHX/Sf7HT8+oCd0/JwJARDeToYHtdqR1Y0HcnbzkUjFivPf073FDJTD1WJ3nUNOv
oKbd5EF4QBcn0zQoUvPjdqskcenQKfIyNYmIM5D5kQ==
-----END RSA PRIVATE KEY-----
`)

var publicKey = string(`
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChSqXhDsX++VxIhy4LnjYcZ1WL
Hoyp6Pc30V6DtT36+iqr4JSSdhfhQACmLFaAnYZJ+7yDsNpsnLO3eBFYQV3S+M/F
6b7eTRxAg/6TTmfPiRI9T3kt+Bkr7bMH+upHYUSJluK7i0DBFp479mKoI5gpFlqk
inj04vaXSEB4GuoglwIDAQAB
-----END PUBLIC KEY-----
`)

var rsaTool *RSASecurity
var once sync.Once

// GetRSATool .
func GetRSATool() *RSASecurity {
	once.Do(func() {
		rsaTool = &RSASecurity{}
		_ = rsaTool.SetPrivateKey(privateKey)
		_ = rsaTool.SetPublicKey(publicKey)
	})
	return rsaTool
}

const (
	//BASE64字符表,不要有重复
	//base64Table        = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
	hashFunctionHeader = "oceanwing"
	hashFunctionFooter = "08.31.11.52"
	base64MoreSafe = false // base64编解码是否再加密一层
)

//var base64Coder = base64.NewEncoding(base64Table)
var base64Coder = base64.URLEncoding
var base64Std = base64.StdEncoding

// Base64StdEncode base64加密
func Base64StdEncode(str string) string {
	if base64MoreSafe {
		str = (hashFunctionHeader + str + hashFunctionFooter)
	}
	return base64Std.EncodeToString([]byte(str))
}

// Base64StdDecode base64解密
func Base64StdDecode(str string) (string, error) {
	src :=[]byte(str)
	by, err := base64Std.DecodeString(string(src))
	if (err == nil) {
		str = string(by)
		if base64MoreSafe {
			str = strings.Replace(strings.Replace(string(by), hashFunctionHeader, "", -1),
				hashFunctionFooter, "", -1)
		}
	}
	return str, err
}

// Base64EncodeToString base64编码
func Base64EncodeToString(src []byte) string {
	return string([]byte(base64Coder.EncodeToString(src)))
}

// Base64DecodeString base64解码
func Base64DecodeString(str string) ([]byte, error) {
	return base64Coder.DecodeString(str)
}

// RsaPubEncrypt rsa公钥加密
func RsaPubEncrypt(src string) string {
	if (len(src) > 0) {
		if cipher, err := GetRSATool().PubKeyEncrypt([]byte(src)); err == nil {
			src = Base64EncodeToString(cipher)
		}
	}
	return src
}

// RsaPriDecrypt rsa私钥解密
func RsaPriDecrypt(src string) string {
	if (len(src) > 0) {
		if decode, err1 := Base64DecodeString(src); err1 == nil {
			if original, err2 := GetRSATool().PriKeyDecrypt(decode); err2 == nil {
				src = string(original)
			}
		}
	}
	return src
}

// Base64JsonDecode base64解码后转json对象
func Base64JsonDecode(str string, obj interface{}) (err error) {
	if len(str) == 0 {
		return
	}
	var jsonBytes []byte
	if jsonBytes, err = base64Coder.DecodeString(str); err == nil {
		err = ffjson.Unmarshal(jsonBytes, obj)
	}
	return
}

// Base64JsonEncode 对象转json串后再base64编码
func Base64JsonEncode(obj interface{}) (ret string, err error) {
	if obj == nil {
		return
	}
	if jsBytes, _ := ffjson.Marshal(obj); len(jsBytes) > 0 {
		ret = base64Coder.EncodeToString(jsBytes)
	}
	return
}

// JsonEncode 对象转json串
func JsonEncode(obj interface{}) (ret string, err error) {
	if obj == nil {
		return
	}
	if jsBytes, _ := ffjson.Marshal(obj); len(jsBytes) > 0 {
		ret = string(jsBytes)
	}
	return
}
